#pragma once

#include "TypedProperty.h"

namespace My {

template <typename T, typename U>
struct PointerToMember {
	U T::* ptr;
	PointerToMember(U T::* p) : ptr(p) { }
	operator U T::* ()
		{ return ptr; }
};

template <typename T>
class CompositeProperty : 
	public virtual BasicProperty<T>,
	public PropertyMap
{
public:
	CompositeProperty(bool expanded = false); 
	CompositeProperty & DefaultExpanded(bool);
public:
	virtual const PropertyMap * GetSubProperties(const EditableList &) const
		{ DoInit(); return this; }
	virtual bool DefaultExpanded() const
		{ return m_Expanded; }
protected:
	virtual void Init() { }
	void DoInit() const;
private:
	mutable bool	m_Init;
	bool			m_Expanded;
};

template <typename T>
class StructProperty : 
	public PropertyImpl<T>, 
	public CompositeProperty<T>
{
public:
	StructProperty(bool expanded = false)
		: CompositeProperty<T>(expanded) { }
	~StructProperty();
public:
	template <typename U>
	PropertyImpl<U> & Create(boost::shared_ptr< ReadWriteAccess<U> > = boost::shared_ptr< ReadWriteAccess<U> >());
	template <typename U>
	PropertyImpl<U> & Create(U T::*);
	template <typename U>
	PropertyImpl<U> & CreatePersistent(boost::shared_ptr< ReadWriteAccess<U> > = boost::shared_ptr< ReadWriteAccess<U> >());
	template <typename U>
	PropertyImpl<U> & CreatePersistent(U T::*);
private:
	std::list<PropertyBase *>	m_AutoCreated;
};

template <typename T>
class GroupProperty : 
	public Property<T>, 
	public CompositeProperty<T> 
{
public:
	GroupProperty(bool expanded = false)
		: CompositeProperty<T>(expanded) { }
};

template <typename T>
class PersistentGroupProperty : 
	public PersistentProperty<T>, 
	public CompositeProperty<T> 
{
public:
	PersistentGroupProperty(bool expanded = false)
		: CompositeProperty<T>(expanded) { }
};

} // My

#include "Impl/CompositeProperty.inl"
